# ========== 1. 在dashboard.py中添加实时日志支持 ==========
import time

from fastapi import APIRouter, Request, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from pathlib import Path
from datetime import datetime
import structlog
import json
import asyncio
from typing import List, Dict, Any
import collections
import queue

from config.settings import settings
from app.services.service_instances import service_discovery

logger = structlog.get_logger(__name__)
router = APIRouter(tags=["Dashboard"])

# 配置模板目录
templates_dir = Path(__file__).parent.parent.parent / "templates"
templates = Jinja2Templates(directory=str(templates_dir))


# 实时日志系统
class RealTimeLogManager:
    def __init__(self):
        self.connections: List[WebSocket] = []
        self.log_queue = queue.Queue(maxsize=1000)
        self.log_history = collections.deque(maxlen=500)  # 保存最近500条日志
        self.stats = {
            "total_requests": 0,
            "total_errors": 0,
            "response_times": collections.deque(maxlen=100),
            "requests_per_minute": 0,
            "last_minute_requests": collections.deque(maxlen=60)
        }

    async def connect(self, websocket: WebSocket):
        """新的WebSocket连接"""
        await websocket.accept()
        self.connections.append(websocket)

        # 发送历史日志
        for log_entry in list(self.log_history):
            try:
                await websocket.send_text(json.dumps(log_entry))
            except:
                pass

        logger.info(f"New WebSocket connection, total: {len(self.connections)}")

    async def disconnect(self, websocket: WebSocket):
        """WebSocket断开连接"""
        if websocket in self.connections:
            self.connections.remove(websocket)
        logger.info(f"WebSocket disconnected, total: {len(self.connections)}")

    async def broadcast_log(self, log_entry: Dict[str, Any]):
        """广播日志到所有连接的客户端"""
        if not self.connections:
            return

        # 添加到历史记录
        self.log_history.append(log_entry)

        # 广播给所有连接的客户端
        disconnected = []
        for websocket in self.connections:
            try:
                await websocket.send_text(json.dumps(log_entry))
            except Exception as e:
                logger.warning(f"Failed to send log to websocket: {e}")
                disconnected.append(websocket)

        # 移除断开的连接
        for ws in disconnected:
            await self.disconnect(ws)

    def add_log(self, level: str, message: str, log_type: str = "info", **kwargs):
        """添加日志条目"""
        log_entry = {
            "timestamp": datetime.now().isoformat(),
            "level": level,
            "message": message,
            "type": log_type,
            "extra": kwargs
        }

        # 异步广播日志
        asyncio.create_task(self.broadcast_log(log_entry))

        # 更新统计
        self.update_stats(level, **kwargs)

    def update_stats(self, level: str, response_time: float = None, **kwargs):
        """更新统计信息"""
        self.stats["total_requests"] += 1

        if level == "error":
            self.stats["total_errors"] += 1

        if response_time:
            self.stats["response_times"].append(response_time)

        # 更新每分钟请求数
        current_minute = datetime.now().minute
        self.stats["last_minute_requests"].append(current_minute)

        # 计算当前分钟的请求数
        current_minute_count = sum(1 for m in self.stats["last_minute_requests"] if m == current_minute)
        self.stats["requests_per_minute"] = current_minute_count


# 全局日志管理器
log_manager = RealTimeLogManager()


@router.websocket("/ws/logs")
async def websocket_logs(websocket: WebSocket):
    """WebSocket端点，用于实时日志推送"""
    await log_manager.connect(websocket)
    try:
        while True:
            # 保持连接活跃，接收客户端ping消息
            data = await websocket.receive_text()
            if data == "ping":
                await websocket.send_text("pong")
    except WebSocketDisconnect:
        await log_manager.disconnect(websocket)


@router.get("/dashboard", response_class=HTMLResponse)
async def gateway_dashboard(request: Request):
    """Gateway 管理仪表板"""
    logger.info("Dashboard page accessed", client_ip=request.client.host if request.client else "unknown")

    template_file = templates_dir / "dashboard.html"
    if not template_file.exists():
        logger.warning(f"Dashboard template not found at {template_file}")
        return HTMLResponse(
            content="""
            <html>
                <head><title>Dashboard Not Found</title></head>
                <body>
                    <h1>Dashboard Template Not Found</h1>
                    <p>Please create the dashboard template at: {}</p>
                    <p><a href="/docs">Go to API Documentation</a></p>
                </body>
            </html>
            """.format(template_file),
            status_code=500
        )

    try:
        return templates.TemplateResponse("dashboard.html", {"request": request})
    except Exception as e:
        logger.error(f"Error rendering dashboard template: {e}")
        return HTMLResponse(
            content=f"""
            <html>
                <head><title>Dashboard Error</title></head>
                <body>
                    <h1>Dashboard Rendering Error</h1>
                    <p>Error: {str(e)}</p>
                    <p><a href="/docs">Go to API Documentation</a></p>
                </body>
            </html>
            """,
            status_code=500
        )


@router.get("/api/dashboard/stats")
async def get_dashboard_stats():
    """获取仪表板统计数据"""
    try:
        services_status = service_discovery.get_service_status()

        total_services = len(services_status)
        healthy_services = sum(1 for status in services_status.values() if status["is_healthy"])

        # 计算平均响应时间
        avg_response_time = 0
        if log_manager.stats["response_times"]:
            avg_response_time = sum(log_manager.stats["response_times"]) / len(log_manager.stats["response_times"])

        # 计算错误率
        error_rate = 0
        if log_manager.stats["total_requests"] > 0:
            error_rate = (log_manager.stats["total_errors"] / log_manager.stats["total_requests"]) * 100

        stats = {
            "total_services": total_services,
            "healthy_services": healthy_services,
            "unhealthy_services": total_services - healthy_services,
            "uptime_percentage": (healthy_services / total_services * 100) if total_services > 0 else 0,
            "total_requests": log_manager.stats["total_requests"],
            "total_errors": log_manager.stats["total_errors"],
            "error_rate": round(error_rate, 2),
            "avg_response_time": round(avg_response_time, 2),
            "requests_per_minute": log_manager.stats["requests_per_minute"],
            "active_connections": len(log_manager.connections),
            "gateway_info": {
                "version": settings.app_version,
                "debug_mode": settings.debug,
                "port": settings.port,
                "rate_limit": f"{settings.rate_limit}/{settings.rate_limit_window}s"
            },
            "timestamp": datetime.now().isoformat()
        }

        return stats

    except Exception as e:
        logger.error(f"Error getting dashboard stats: {e}")
        return {
            "error": "Failed to get dashboard stats",
            "total_services": 0,
            "healthy_services": 0,
            "unhealthy_services": 0,
            "uptime_percentage": 0,
            "total_requests": 0,
            "total_errors": 0,
            "error_rate": 0,
            "gateway_info": {
                "version": settings.app_version,
                "debug_mode": settings.debug,
                "port": settings.port,
                "rate_limit": f"{settings.rate_limit}/{settings.rate_limit_window}s"
            },
            "timestamp": datetime.now().isoformat()
        }


@router.get("/api/dashboard/logs/history")
async def get_log_history(limit: int = 100):
    """获取历史日志"""
    try:
        logs = list(log_manager.log_history)[-limit:]
        return {"logs": logs, "count": len(logs)}
    except Exception as e:
        logger.error(f"Error getting log history: {e}")
        return {"logs": [], "count": 0, "error": str(e)}


@router.post("/api/dashboard/logs/test")
async def test_log_broadcast():
    """测试日志广播功能"""
    test_logs = [
        ("info", "测试日志广播功能", "system"),
        ("warning", "这是一条警告日志", "test"),
        ("error", "这是一条错误日志", "test"),
        ("success", "这是一条成功日志", "test")
    ]

    for level, message, log_type in test_logs:
        log_manager.add_log(level, message, log_type)
        await asyncio.sleep(0.5)  # 间隔0.5秒

    return {"message": "测试日志已发送", "count": len(test_logs)}
